#ifndef _VERSION_H
#define _VERSION_H

extern const char *_VERSION_STATES[];
extern char _STRING_STATIC[];

typedef u32 ver_t;

#define _byte(a) ((a)&0xFF)
#define _ver(a) ((ver_t)(a))

enum eVERSION_STATE_STATE {
    STATE_ALPHA=0,
    STATE_BETA,
    STATE_RC,
    STATE_NORMAL
};

#define MAKE_VERSION(major, minor, patch, state, state_n) _ver( \
        (_byte(major)<<24) | \
        (_byte(minor)<<16) | \
        (_byte(patch)<<8) | \
        (((state)&0x3)<<6) | \
        ((state_n)&0x3F) \
    )

#define VERSION_MAJOR(v)        _byte(_ver(v)>>24)
#define VERSION_MINOR(v)        _byte(_ver(v)>>16)
#define VERSION_PATCH(v)        _byte(_ver(v)>>8)
#define VERSION_STATE_STATE(v)  ((_ver(v)>>6)&0x3)
#define VERSION_STATE_NUM(v)    (_ver(v)&0x3F)
char *VERSION_STATE(ver_t v);
#define VERSION_STATE_STR_MAX_LEN (5)

#define VERSION_FORMAT "%d.%d.%d%s"
#define VERSION_ARGS(v) \
    VERSION_MAJOR(v), \
    VERSION_MINOR(v), \
    VERSION_PATCH(v), \
    VERSION_STATE(v)
#define VERSION_STR_MAX_LEN (3+1+3+1+3+VERSION_STATE_STR_MAX_LEN)

#define VERSION_IS_COMPATIBLE(host, local) ( \
        VERSION_MAJOR(host)==VERSION_MAJOR(local) && \
        VERSION_MINOR(host)==VERSION_MINOR(local) && \
        VERSION_PATCH(host)>=VERSION_PATCH(local) \
    )

#endif

